/*
 * @(#)LuaTableUtil.java        1.0 2009-6-19
 *
 * Copyright (c) 2007-2009 Shanghai Handpay IT, Co., Ltd.
 * 16/F, 889 YanAn Road. W., Shanghai, China
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of 
 * Shanghai Handpay IT Co., Ltd. ("Confidential Information").  
 * You shall not disclose such Confidential Information and shall use 
 * it only in accordance with the terms of the license agreement you 
 * entered into with Handpay.
 */

package com.handpay.framework;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Vector;

import se.krka.kahlua.luaj.compiler.LuaCompiler;
import se.krka.kahlua.vm.LuaClosure;
import se.krka.kahlua.vm.LuaPrototype;
import se.krka.kahlua.vm.LuaState;
import se.krka.kahlua.vm.LuaTable;
import android.util.Log;

import com.handpay.zztong.hp.log.HPLog;

/**
 * LuaTable处理方法
 * 
 * @version 1.0 2009-6-19
 * @author Wen Tao history 2009-6-19 Wen Tao 1.0 创建
 */
public class LuaTableUtil {
	
	private static LuaClosure loadScript(byte[] data, boolean compiled,
			LuaState state, String name)
	{
		LuaClosure lc;
		try
		{
			if (compiled)
			{
				
				lc = LuaPrototype.loadByteCode(new ByteArrayInputStream(data),
						state.getEnvironment());
			}
			else
			{
				lc = LuaCompiler.loadis(new ByteArrayInputStream(data), /* "<stdin>" */
						name, state.getEnvironment());
			}
			return lc;
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	private static LuaTable readData(byte[] data, boolean compiled, String name)// Caojun
	{
		LuaClosure lc = null;
		
		LuaState dataState = new LuaState();
		LuaTable dataObj = null;
		try
		{
			lc = loadScript(data, compiled, dataState, name);
			
			dataState.call(lc, null, null, null);
			dataObj = LuaTableUtil.getLuaTable(dataState.getEnvironment(),
					"data");
		}
		catch (Exception e)
		{
			HPLog.e("LuaTable", "",e);
			return null;
		}
		lc = null;
		// dataState.release();
		dataState = null;
		return dataObj;
	}
	
	/**
	 * 读取key键值的数据，如果值不存在，则返回缺省值
	 * 
	 * @param obj
	 * @param key
	 * @return
	 */
	public static Integer getInteger(LuaTable obj, String key) {
		if (obj == null)
			return null;
		Object intObj = obj.rawget(key);
		if (intObj != null && intObj instanceof Double) {
			long longn=((Double) intObj).longValue();
			int intn=(int)longn;
			return new Integer(intn);
		}

		return null;
	}

	public static Long getLong(LuaTable obj, String key) {
		if (obj == null)
			return null;
		Object intObj = obj.rawget(key);
		if (intObj != null && intObj instanceof Double) {
			return new Long(((Double) intObj).intValue());
		}
		return null;
	}

	public static String getString(LuaTable obj, String key, String defaultValue) {
		if (obj == null)
			return defaultValue;
		Object intObj = obj.rawget(key);
		if (intObj != null && intObj instanceof String) {
			return (String) intObj;
		}

		return defaultValue;
	}

	public static LuaTable getLuaTable(LuaTable obj, Object key) {
		if (obj == null)
			return null;
		Object tblObj = obj.rawget(key);
		if (tblObj != null && tblObj instanceof LuaTable) {
			return (LuaTable) tblObj;
		}

		return null;
	}

	public static Boolean getBoolean(LuaTable obj, String key) {
		if (obj == null)
			return null;
		Object boolObj = obj.rawget(key);
		if (boolObj != null && boolObj instanceof Boolean) {
			return (Boolean) boolObj;
		}

		return null;
	}

	public static LuaClosure getFunction(LuaTable obj, String key) {
		if (obj == null)
			return null;
		Object funcObj = obj.rawget(key);
		if (funcObj != null && funcObj instanceof LuaClosure) {
			return (LuaClosure) funcObj;
		}

		return null;
	}

	public static int tableLength(LuaTable table){
		if (table == null) {
			return 0;
		}
		Object key = null;
		int len = 0;
		key = table.next(key);
		while (key!=null) {
			len++;
			key = table.next(key);
		}
		return len;
	}
	
	public static void printTable(LuaTable table) {
		if (table == null) {
			return;
		}
		Object key = null;
		while (true) {
			Object nk = table.next(key);
			if (nk == null)
				break;
			Object value = table.rawget(nk);
//			LogManager.debug("LuaTable", value == null ? "null" : value
//					.getClass().toString());
			if (value instanceof LuaTable) {
				LuaTableUtil.printTable((LuaTable) value);
			} else {
//				LogManager.debug("LuaTable", nk + ": " + table.rawget(nk));
				HPLog.d(HPLog.YL_TAG, nk + ": " + table.rawget(nk));
			}
			key = nk;
		}
	}

//	public static Vector<Command> getCommandArray(LuaTable obj){
//		if (obj == null) {
//			return null;
//		}
//		Vector<Command> v = new Vector<Command>();
//		Object key = null;
//		while ((key = obj.next(key)) != null) {
//			if (key instanceof Double) {
//			} else {
//				continue;
//			}
//			LuaTable itemObj = LuaTableUtil.getLuaTable(obj, key);
//			// Item item = UIAccess.getUIAccess().createItem(itemObj);
//			Command item=new Command();
//			item.setDataObj(itemObj);
//			if(item!=null){
//				int index=((Double)key).intValue()-1;
//				if (v.size() <= index) {
//					v.setSize(index + 1);
//				}
//				v.setElementAt(item, index);
//			}
//			// Log.systemout(v.size()+", "+index);
//		}
//		return v;		
//	}

	/** 此方法获得的是直接的object值 如{a,b,c,d} vector=a,b,c,d */
	public static Vector<?> getArrayList(LuaTable obj) {
		if (obj == null) {
			return null;
		}

		Vector<Object> v = new Vector<Object>();
		Object key = null;
		int index = 0;
		while ((key = obj.next(key)) != null) {
			if (key instanceof Double) {
				index = (int) LuaState.fromDouble(key) - 1;
			} else {
				continue;
			}
			Object intObj = obj.rawget(key);
			if (intObj != null) {
				if (v.size() <= index) {
					v.setSize(index + 1);
				}
				v.setElementAt(intObj, index);
			}
		}
		return v;
	}
	
	/**
	 * 字符串转LuaTable
	 * 
	 * @param data
	 * @return
	 */
	public static LuaTable stringToLuaTable(byte data[], boolean compiled)
	{
//		LuaTable resultdata=new LuaTableImpl();
//		ScriptEngine se = ScriptEngine.getInstance();
//		if (se != null) {
//			LuaTable data = se.readData(this.data, compiled, "NetData.getResultData");
//			resultdata.rawset("data", data);
//		}
//		return resultdata;
		return readData(data,compiled,"stringToLuaTable");
	}
	/**
	 * 字符串转LuaTable
	 * 
	 * @param data
	 * @return
	 */
	public static LuaTable stringToLuaTable(byte data[])
	{
		return stringToLuaTable(data,false);
	}

	/**
	 * 把LuaTable转换成字符串
	 * 
	 */
	public static String luaTableToString(LuaTable data) {
		StringBuffer s = new StringBuffer("{");
		// Log.systemout(data.len());
		// Log.systemout(data.next(data.next(null)));

		Object key = null;

		while ((key = data.next(key)) != null)
			if (!(key instanceof Double)) {

				s.append(key).append("=");

				Object tblObj = data.rawget(key);

				if (tblObj instanceof LuaTable)
					s.append(luaTableToString((LuaTable) tblObj));
				else if (tblObj instanceof String)
					s.append("\"").append(tblObj).append("\"");
				else
					s.append(tblObj);

				s.append(",");

			}

		Vector<?> array = getArrayList(data);

		for (int i = 0; i < array.size(); i++) {

			Object tblObj = array.elementAt(i);

			if (tblObj instanceof LuaTable)
				s.append(luaTableToString((LuaTable) tblObj));
			else if (tblObj instanceof String)
				s.append("\"").append(tblObj).append("\"");
			else
				s.append(tblObj);

			s.append(",");

		}

		s.append("}");

//		LogManager.debug("LuaTable ", s.toString());
		Log.d("LuaTable", s.toString());

		return s.toString();

	}

	public static Vector<LuaTable> getArray(LuaTable obj)
	{
		if (obj == null)
		{
			return null;
		}
		Object key = null;
		int index = 0;
		Vector<LuaTable> v = new Vector<LuaTable>();
		while ((key = obj.next(key)) != null)
		{
			if (key instanceof Double)
			{
				index = (int) LuaState.fromDouble(key) - 1;
			}
			else
			{
				continue;
			}
			LuaTable itemObj = LuaTableUtil.getLuaTable(obj, key);
			if(itemObj != null)
			{
				if (v.size() <= index)
				{
					v.setSize(index + 1);
				}
				v.setElementAt(itemObj, index);	
			}
		}
		return v;
	}
}
